﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace LearnDI
{
    public static class DenpendencyInjectExtension
    {
        public static IServiceCollection AddDenpendencyInject(this IServiceCollection services)
        {

            
            var baseType = typeof(IDI);
            var xbaseType = typeof(IClassX);

            var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
            var referencedAssemblies = System.IO.Directory.GetFiles(path, "*.dll").Select(Assembly.LoadFrom).ToArray();
            var types = referencedAssemblies
                .SelectMany(a => a.DefinedTypes)
                .Select(type => type.AsType())
                .Where(x => x != baseType && baseType.IsAssignableFrom(x)).ToArray();
            var implementTypes = types.Where(x => x.IsClass && x != xbaseType && !xbaseType.IsAssignableFrom(x)).ToArray();
            var interfaceTypes = types.Where(x => x.IsInterface && x != xbaseType && !xbaseType.IsAssignableFrom(x)).ToArray();
            foreach (var implementType in implementTypes)
            {
                var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType));
                if (interfaceType != null)
                    services.AddScoped(interfaceType, implementType);
            }

            // clickhouse 开关,重新注册ClickHouse的相关Service
            if (true)
            {
                var XimplementTypes = types.Where(x => x.IsClass && xbaseType.IsAssignableFrom(x)).ToArray();

                foreach (var interfaceType in interfaceTypes)
                {
                    var implementType = XimplementTypes.FirstOrDefault(x => x.IsAssignableTo(interfaceType));
                    if (implementType != null)
                        services.AddScoped(interfaceType, implementType);
                }
            }

            return services;
        }
    }
}
